<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.23">
<meta name="description" content="Learn about the USBX Device Class considerations.">
<title>Chapter 5 - USBX Device Class Considerations</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.square{list-style-type:square}
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
</head>
<body class="article">
<div id="header">
<h1>Chapter 5 - USBX Device Class Considerations</h1>
</div>
<div id="content">
<div class="sect1">
<h2 id="_device_class_registration">Device Class registration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Each device class follows the same principle for registration. A structure containing specific class parameters is passed to the class initialize function.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Set the parameters for callback when insertion/extraction of a HID device. */

hid_parameter.ux_slave_class_hid_instance_activate = tx_demo_hid_instance_activate;

hid_parameter.ux_slave_class_hid_instance_deactivate = tx_demo_hid_instance_deactivate;

/* Initialize the hid class parameters for the device. */
hid_parameter.ux_device_class_hid_parameter_report_address = hid_device_report;

hid_parameter.ux_device_class_hid_parameter_report_length = HID_DEVICE_REPORT_LENGTH;

hid_parameter.ux_device_class_hid_parameter_report_id = UX_TRUE;
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;

/* Initialize the device hid class. The class is connected with interface 0 */

status = ux_device_stack_class_register(_ux_system_slave_class_hid_name,
    ux_device_class_hid_entry,1,0, (VOID *)&amp;hid_parameter);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each class can register, optionally, a callback function when a instance of the class gets activated. The callback is then called by the device stack to inform the application that an instance was created.</p>
</div>
<div class="paragraph">
<p>The application would have in its body the 2 functions for activation and deactivation, as shown in the following example.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">VOID tx_demo_hid_instance_activate(VOID *hid_instance)
{
    /* Save the HID instance. */
    hid_slave = (UX_SLAVE_CLASS_HID *) hid_instance;
}

VOID tx_demo_hid_instance_deactivate(VOID *hid_instance)
{
    /* Reset the HID instance. */
    hid_slave = UX_NULL;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is not recommended to do anything within these functions but to memorize the instance of the class and synchronize with the rest of the application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_general_considerations_for_bulk_transfer">General Considerations for Bulk Transfer</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As per the USB 2.0 specification, an endpoint must always transmit data payloads with a data field less than or equal to the endpoint&#8217;s
reported wMaxPacketSize value. The size of a data packet is limited to bMaxPacketSize. Transfer can be completed with the following cases</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The endpoint has transferred exactly the amount of data expected</p>
</li>
<li>
<p>When a device or host endpoint receives a packet with size less than max packet size(wMaxPacketSize). This short packet indicates that there is no more data packet left and transfer is complete or when the data packets to be transmitted are all equal to wMaxPacketSize, then the end of transfer cannot be determined. In order for transfer completion a Zero Length Packet(ZLP) must be sent
Short packets and Zero Length Packets signify the end of a bulk data transfer.
The above considerations apply to raw bulk data transfer APIs, e.g., ux_device_class_cdc_acm_read().</p>
</li>
</ol>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_usb_device_storage_class">USB Device Storage Class</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The USB device storage class allows for a storage device embedded in the system to be made visible to a USB host.</p>
</div>
<div class="paragraph">
<p>The USB device storage class does not by itself provide a storage solution. It merely accepts and interprets SCSI requests coming from the host. When one of these requests is a read or a write command, it will invoke a pre-defined call back to a real storage device handler, such as an ATA device driver or a Flash device driver.</p>
</div>
<div class="paragraph">
<p>When initializing the device storage class, a pointer structure is given to the class that contains all the information necessary. An example is given below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Initialize the storage class parameters to customize vendor strings. */

storage_parameter.ux_slave_class_storage_parameter_vendor_id
    = demo_ux_system_slave_class_storage_vendor_id;

storage_parameter.ux_slave_class_storage_parameter_product_id
    = demo_ux_system_slave_class_storage_product_id;

storage_parameter.ux_slave_class_storage_parameter_product_rev
    = demo_ux_system_slave_class_storage_product_rev;

storage_parameter.ux_slave_class_storage_parameter_product_serial
    = demo_ux_system_slave_class_storage_product_serial;

/* Store the number of LUN in this device storage instance: single LUN. */
storage_parameter.ux_slave_class_storage_parameter_number_lun = 1;

/* Initialize the storage class parameters for reading/writing to the Flash Disk. */

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba = 0x1e6bfe;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = 512;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read_only_flag
    = UX_FALSE;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read
    = tx_demo_thread_flash_media_read;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write
    = tx_demo_thread_flash_media_write;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status
    = tx_demo_thread_flash_media_status;

/* A simple write caching support.
   If this callback is assigned, host gets notification from caching page
   that write caching is supported, and can send SYNCHRONIZE_CACHE to
   flush cache. But caching options are not allowed to be changed.  */
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_flush  =
   tx_demo_thread_flash_media_flush;

/* Initialize the device storage class. The class is connected with interface 0 */
status = ux_device_stack_class_register(_ux_system_slave_class_storage_name,
    ux_device_class_storage_entry, ux_device_class_storage_thread, 0, (VOID *)&amp;storage_parameter);</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, the driver storage strings are customized by assigning string pointers to corresponding parameter. If any one of the string pointer is left to UX_NULL, the default ThreadX string is used.</p>
</div>
<div class="paragraph">
<p>In this example, the drive&#8217;s last block address or LBA is given as well as the logical sector size. The LBA is the number of sectors available in the media --1. The block length is set to 512 in regular storage media. It can be set to 2048 for optical drives.</p>
</div>
<div class="paragraph">
<p>The application needs to pass three callback function pointers to allow the storage class to read, write and obtain status for the media.</p>
</div>
<div class="paragraph">
<p>The prototypes for the read and write functions are shown in the example below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT media_read(
    VOID *storage,
    ULONG lun,
    UCHAR *data_pointer,
    ULONG number_blocks,
    ULONG lba,
    ULONG *media_status);

UINT media_write(
    VOID *storage,
    ULONG lun,
    UCHAR *data_pointer,
    ULONG number_blocks,
    ULONG lba,
    ULONG *media_status);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>storage</em> is the instance of the storage class.</p>
</li>
<li>
<p><em>lun</em> is the LUN the command is directed to.</p>
</li>
<li>
<p><em>data_pointer</em> is the address of the buffer to be used for reading or writing.</p>
</li>
<li>
<p><em>number_blocks</em> is the number of sectors to read/write.</p>
</li>
<li>
<p><em>lba</em> is the sector address to read.</p>
</li>
<li>
<p><em>media_status</em> should be filled out exactly like the media status callback return value.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The return value can have either the value UX_SUCCESS or UX_ERROR indicating a successful or unsuccessful operation. These operations do not need to return any other error codes. If there is an error in any operation, the storage class will invoke the status call back function.</p>
</div>
<div class="paragraph">
<p>This function has the following prototype.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">ULONG media_status(
    VOID *storage,
    ULONG lun,
    ULONG media_id,
    ULONG *media_status);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The calling parameter media_id is not currently used and should always be 0. In the future it may be used to distinguish multiple storage devices or storage devices with multiple SCSI LUNs. This version of the storage class does not support multiple instances of the storage class or storage devices with multiple SCSI LUNs.</p>
</div>
<div class="paragraph">
<p>The return value is a SCSI error code that can have the following format.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Bits 0-7</strong> Sense_key</p>
</li>
<li>
<p><strong>Bits 8-15</strong> Additional Sense Code</p>
</li>
<li>
<p><strong>Bits 16-23</strong> Additional Sense Code Qualifier</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following table provides the possible Sense/ASC/ASCQ combinations.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Sense Key</th>
<th class="tableblock halign-left valign-top">ASC</th>
<th class="tableblock halign-left valign-top">ASCQ</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NO SENSE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">17</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RECOVERED DATA WITH RETRIES</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">18</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RECOVERED DATA WITH ECC</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL DRIVE NOT READY - BECOMING READY</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL DRIVE NOT READY - INITIALIZATION REQUIRED</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL UNIT NOT READY - FORMAT IN PROGRESS</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL DRIVE NOT READY - DEVICE IS BUSY</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">06</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NO REFERENCE POSITION FOUND</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">08</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL UNIT COMMUNICATION FAILURE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">08</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL UNIT COMMUNICATION TIME-OUT</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">08</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">80</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL UNIT COMMUNICATION OVERRUN</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3A</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">MEDIUM NOT PRESENT</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">54</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">USB TO HOST SYSTEM INTERFACE FAILURE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">80</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">INSUFFICIENT RESOURCES</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UNKNOWN ERROR</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NO SEEK COMPLETE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">WRITE FAULT</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ID CRC ERROR</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UNRECOVERED READ ERROR</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">12</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ADDRESS MARK NOT FOUND FOR ID FIELD</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ADDRESS MARK NOT FOUND FOR DATA FIELD</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">14</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RECORDED ENTITY NOT FOUND</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">30</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CANNOT READ MEDIUM - UNKNOWN FORMAT</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">31</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FORMAT COMMAND FAILED</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">40</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NN</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">DIAGNOSTIC FAILURE ON COMPONENT NN (80H-FFH)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1A</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">PARAMETER LIST LENGTH ERROR</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">INVALID COMMAND OPERATION CODE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL BLOCK ADDRESS OUT OF RANGE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">24</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">INVALID FIELD IN COMMAND PACKET</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">25</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LOGICAL UNIT NOT SUPPORTED</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">26</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">INVALID FIELD IN PARAMETER LIST</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">26</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">PARAMETER NOT SUPPORTED</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">26</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">PARAMETER VALUE INVALID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">39</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">SAVING PARAMETERS NOT SUPPORT</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">06</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">28</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NOT READY TO READY TRANSITION&#8201;&#8212;&#8201;MEDIA CHANGED</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">06</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">29</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">POWER ON RESET OR BUS DEVICE RESET OCCURRED</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">06</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2F</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">COMMANDS CLEARED BY ANOTHER INITIATOR</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">07</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">27</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">WRITE PROTECTED MEDIA</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">0B</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4E</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">00</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">OVERLAPPED COMMAND ATTEMPTED</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>There are two additional, optional callbacks the application may implement; one is for responding to a <strong>GET_STATUS_NOTIFICATION</strong> command and the other is for responding to the <strong>SYNCHRONIZE_CACHE</strong> command.</p>
</div>
<div class="paragraph">
<p>If the application would like to handle the <strong>GET_STATUS_NOTIFICATION</strong> command from the host, it should implement a callback with the following prototype.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_slave_class_storage_media_notification(
    VOID *storage,
    ULONG lun,
    ULONG media_id,
    ULONG notification_class,
    UCHAR **media_notification,
    ULONG *media_notification_length);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>storage</em> is the instance of the storage class.</p>
</li>
<li>
<p><em>media_id</em> is not currently used. notification_class specifies the class of notification.</p>
</li>
<li>
<p><em>media_notification</em> should be set by the application to the buffer containing the response for the notification.</p>
</li>
<li>
<p><em>media_notification_length</em> should be set by the application to contain the length of the response buffer.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The return value indicates whether or not the command succeeded&#8201;&#8212;&#8201;should be either <strong>UX_SUCCESS</strong> or <strong>UX_ERROR</strong>.</p>
</div>
<div class="paragraph">
<p>If the application does not implement this callback, then upon receiving the <strong>GET_STATUS_NOTIFICATION</strong> command, USBX will notify the host that the command is not implemented.</p>
</div>
<div class="paragraph">
<p>The <strong>SYNCHRONIZE_CACHE</strong> command should be handled if the application is utilizing a cache for writes from the host. A host may send this command if it knows the storage device is about to be disconnected, for example, in Windows, if you right click a flash drive icon in the toolbar and select "Eject [storage device name]", Windows will issue the <strong>SYNCHRONIZE_CACHE</strong> command to that device.</p>
</div>
<div class="paragraph">
<p>If the application would like to handle the <strong>SYNCHRONIZE_CACHE</strong> command from the host, it should implement a callback with the following prototype.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_slave_class_storage_media_flush(
    VOID *storage,
    ULONG lun,
    ULONG number_blocks,
    ULONG lba,
    ULONG *media_status);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>storage</em> is the instance of the storage class.</p>
</li>
<li>
<p><em>lun</em> parameter specifies which LUN the command is directed to.</p>
</li>
<li>
<p><em>number_blocks</em> specifies the number of blocks to synchronize.</p>
</li>
<li>
<p><em>lba</em> is the sector address of the first block to synchronize.</p>
</li>
<li>
<p><em>media_status</em> should be filled out exactly like the media status callback return value.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The return value indicates whether or not the command succeeded&#8201;&#8212;&#8201;should be either <strong>UX_SUCCESS</strong> or <strong>UX_ERROR</strong>.</p>
</div>
<div class="sect2">
<h3 id="_multiple_scsi_lun">Multiple SCSI LUN</h3>
<div class="paragraph">
<p>The USBX device storage class supports multiple LUNs. It is therefore possible to create a storage device that acts as a CD-ROM and a Flash disk at the same time. In such a case, the initialization would be slightly different. Here is an example for a Flash Disk and CD-ROM:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Store the number of LUN in this device storage instance. */
storage_parameter.ux_slave_class_storage_parameter_number_lun = 2;

/* Initialize the storage class parameters for reading/writing to the Flash Disk. */
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba = 0x7bbff;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = 512;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = tx_demo_thread_flash_media_read;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = tx_demo_thread_flash_media_write;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = tx_demo_thread_flash_media_status;

/* Initialize the storage class LUN parameters for reading/writing to the CD-ROM. */

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_last_lba = 0x04caaf;

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_block_length = 2048;

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_type = 5;

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_removable_flag = 0x80;

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read = tx_demo_thread_cdrom_media_read;

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_write = tx_demo_thread_cdrom_media_write;

storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_status = tx_demo_thread_cdrom_media_status;

/* Initialize the device storage class for a Flash disk and CD-ROM. The class is connected with interface 0 */ status = ux_device_stack_class_register(_ux_system_slave_class_storage_name,ux_device_class_storage_entry,
    ux_device_class_storage_thread,0, (VOID *) &amp;storage_parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_write_caching_scsi_lun">Write Caching SCSI LUN</h3>
<div class="paragraph">
<p>The USBX device storage class supports write caching on LUNs.</p>
</div>
<div class="paragraph">
<p>The application needs to pass a callback function pointer to allow the storage class to report write caching enable to host and do flushing on host request.</p>
</div>
<div class="paragraph">
<p>The flush callback function has the following prototype:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT    media_flush(VOID *storage, ULONG lun, ULONG number_blocks,    ULONG lba, ULONG *media_status);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The calling parameter <em>number_blocks</em> and <em>lba</em> specifies the area on LUN that needs flush.</p>
</div>
<div class="paragraph">
<p>Note that when the callback is not assigned, host is not notified for write caching support, so there is no option for it. When the callback is assigned, host is notified for write caching enabled, but not allowed to change this setting.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_usb_device_cdc_acm_class">USB Device CDC-ACM Class</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The USB device CDC-ACM class allows for a USB host system to communicate with the device as a serial device. This class is based on the USB standard and is a subset of the CDC standard.</p>
</div>
<div class="paragraph">
<p>A CDC-ACM compliant device framework needs to be declared by the device stack. An example is found here below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">unsigned char device_framework_full_speed[] = {

    /*
    Device descriptor 18 bytes
    0x02 bDeviceClass: CDC class code
    0x00 bDeviceSubclass: CDC class sub code 0x00 bDeviceProtocol: CDC Device protocol
    idVendor &amp; idProduct - https://www.linux-usb.org/usb.ids
    */

    0x12, 0x01, 0x10, 0x01,
    0xEF, 0x02, 0x01, 0x08,
    0x84, 0x84, 0x00, 0x00,
    0x00, 0x01, 0x01, 0x02,
    0x03, 0x01,

    /* Configuration 1 descriptor 9 bytes */
    0x09, 0x02, 0x4b, 0x00, 0x02, 0x01, 0x00,0x40, 0x00,

    /* Interface association descriptor. 8 bytes. */
    0x08, 0x0b, 0x00,
    0x02, 0x02, 0x02, 0x00, 0x00,

    /* Communication Class Interface Descriptor Requirement. 9 bytes. */
    0x09, 0x04, 0x00, 0x00,0x01,0x02, 0x02, 0x01, 0x00,

    /* Header Functional Descriptor 5 bytes */
    0x05, 0x24, 0x00,0x10, 0x01,

    /* ACM Functional Descriptor 4 bytes */
    0x04, 0x24, 0x02,0x0f,

    /* Union Functional Descriptor 5 bytes */
    0x05, 0x24, 0x06, 0x00,

    /* Master interface */
    0x01, /* Slave interface */

    /* Call Management Functional Descriptor 5 bytes */
    0x05, 0x24, 0x01,0x03, 0x01, /* Data interface */

    /* Endpoint 1 descriptor 7 bytes */
    0x07, 0x05, 0x83, 0x03,0x08, 0x00, 0xFF,

    /* Data Class Interface Descriptor Requirement 9 bytes */
    0x09, 0x04, 0x01, 0x00, 0x02,0x0A, 0x00, 0x00, 0x00,

    /* First alternate setting Endpoint 1 descriptor 7 bytes*/
    0x07, 0x05, 0x02,0x02,0x40, 0x00,0x00,

    /* Endpoint 2 descriptor 7 bytes */
    0x07, 0x05, 0x81,0x02,0x40, 0x00, 0x00,

};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The CDC-ACM class uses a composite device framework to group interfaces (control and data). As a result care should be taken when defining the device descriptor. <strong>USBX relies on the interface association descriptor (IAD) to know internally how to bind interfaces</strong>. The IAD descriptor should be declared before the interfaces and contain the first interface of the CDC-ACM class and how many interfaces are attached.</p>
</div>
<div class="paragraph">
<p>The CDC-ACM class also uses a union functional descriptor which performs the same function as the newer IAD descriptor. Although a Union Functional descriptor must be declared for historical reasons and compatibility with the host side, it is not used by USBX.</p>
</div>
<div class="paragraph">
<p>The initialization of the CDC-ACM class expects the following parameters.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Set the parameters for callback when insertion/extraction of a CDC device. */

parameter.ux_slave_class_cdc_acm_instance_activate = tx_demo_cdc_instance_activate;

parameter.ux_slave_class_cdc_acm_instance_deactivate = tx_demo_cdc_instance_deactivate;

parameter.ux_slave_class_cdc_acm_parameter_change = tx_demo_cdc_instance_parameter_change;

/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name,ux_device_class_cdc_acm_entry,
    1,0, &amp;parameter);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The 2 parameters defined are callback pointers into the user applications that will be called when the stack activates or deactivate this class.</p>
</div>
<div class="paragraph">
<p>The third parameter defined is a callback pointer to the user application that will be called when there is line coding or line states parameter change. E.g., when there is request from host to change DTR state to <strong>TRUE</strong>, the callback is invoked, in it user application can check line states through IOCTL function to kow host is ready for communication.</p>
</div>
<div class="paragraph">
<p>The CDC-ACM is based on a USB-IF standard and is automatically recognized by MACOs and Linux operating systems. On Windows platforms, this class requires a .inf file for Windows version prior to 10. Windows 10 does not require any .inf files. We supply a template for the CDC-ACM class and it can be found in the <strong><em>usbx_windows_host_files</em></strong> directory. For more recent version of Windows the file CDC_ACM_Template_Win7_64bit.inf should be used (except Win10). This file needs to be modified to reflect the PID/VID used by the device. The PID/VID will be specific to the final customer when the company and the product are registered with the USB-IF. In the inf file, the fields to modify are located here.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-INF" data-lang="INF">[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_8484&amp;PID_0000

[DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_8484&amp;PID_0000</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the device framework of the CDC-ACM device, the PID/VID are stored in the device descriptor (see the device descriptor declared above).</p>
</div>
<div class="paragraph">
<p>When a USB host systems discovers the USB CDC-ACM device, it will mount a serial class and the device can be used with any serial terminal program. See the host Operating System for reference.</p>
</div>
<div class="paragraph">
<p>The CDC-ACM class API functions are defined below.</p>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl">ux_device_class_cdc_acm_ioctl</h3>
<div class="paragraph">
<p>Perform IOCTL on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to perform various ioctl calls to the cdc acm interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: Ioctl function to be performed.</p>
</li>
<li>
<p><strong>parameter</strong>: Pointer to a parameter specific to the ioctl call.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_return_value">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_ERROR</strong> (0xFF) Error from function</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Start cdc acm callback transmission. */

status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START, &amp;callback);

if(status != UX_SUCCESS)
    return;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ioctl_functions">Ioctl functions:</h3>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Function</th>
<th class="tableblock halign-left valign-top">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_STATE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_STOP</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">7</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_set_line_coding">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING</h3>
<div class="paragraph">
<p>Perform IOCTL Set Line Coding on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_2">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM*cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_2">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to Set the Line Coding parameters.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_2">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING</p>
</li>
<li>
<p><strong>parameter</strong>: Pointer to a line parameter structure:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER_STRUCT
{
    ULONG ux_slave_class_cdc_acm_parameter_baudrate;
    UCHAR ux_slave_class_cdc_acm_parameter_stop_bit;
    UCHAR ux_slave_class_cdc_acm_parameter_parity;
    UCHAR ux_slave_class_cdc_acm_parameter_data_bit;
} UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_2">Return Value</h3>
<div class="paragraph">
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</div>
</div>
<div class="sect2">
<h3 id="_example_2">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Change the line coding values. */

line_coding.ux_slave_class_cdc_acm_line_coding_dter = 9600;
line_coding.ux_slave_class_cdc_acm_line_coding_stop_bit =
    UX_HOST_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_15;

line_coding.ux_slave_class_cdc_acm_line_coding_parity =
    UX_HOST_CLASS_CDC_ACM_LINE_CODING_PARITY_EVEN;

line_coding.ux_slave_class_cdc_acm_line_coding_data_bits = 5;

status = _ux_slave_class_cdc_acm_ioctl(cdc_acm,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING, &amp;line_coding);

if (status != UX_SUCCESS)
    break;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_get_line_coding">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING</h3>
<div class="paragraph">
<p>Perform IOCTL Get Line Coding on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_3">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_3">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to Get the Line Coding parameters.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_3">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_GET_ LINE_CODING</p>
</li>
<li>
<p><strong>parameter</strong>: Pointer to a line parameter structure:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER_STRUCT
{
    ULONG ux_slave_class_cdc_acm_parameter_baudrate;
    UCHAR ux_slave_class_cdc_acm_parameter_stop_bit;
    UCHAR ux_slave_class_cdc_acm_parameter_parity;
    UCHAR ux_slave_class_cdc_acm_parameter_data_bit;
} UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_3">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_3">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* This is to retrieve BAUD rate. */

status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &amp;line_coding);

/* Any error ? */
if (status == UX_SUCCESS)
{
    /* Decode BAUD rate. */
    switch (line_coding.ux_slave_class_cdc_acm_parameter_baudrate)
    {
        case 1200 :
            status = tx_demo_thread_slave_cdc_acm_response("1200", 4);
            break;
        case 2400 :
            status = tx_demo_thread_slave_cdc_acm_response("2400", 4);
            break;
        case 4800 :
            status = tx_demo_thread_slave_cdc_acm_response("4800", 4);
            break;
        case 9600 :
            status = tx_demo_thread_slave_cdc_acm_response("9600", 4);
            break;
        case 115200 :
            status = tx_demo_thread_slave_cdc_acm_response("115200", 6);
            break;
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_get_line_state">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE</h3>
<div class="paragraph">
<p>Perform IOCTL Get Line State on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_4">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM*cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_4">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to Get the Line State parameters.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_4">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE</p>
</li>
<li>
<p><strong>parameter</strong>: Pointer to a line parameter structure:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER_STRUCT
{
    UCHAR ux_slave_class_cdc_acm_parameter_rts;
    UCHAR ux_slave_class_cdc_acm_parameter_dtr;
} UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_4">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_4">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* This is to retrieve RTS state. */
status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &amp;line_state);

/* Any error ? */
if (status == UX_SUCCESS)
{
/* Check state. */
    if (line_state.ux_slave_class_cdc_acm_parameter_rts == UX_TRUE)
        /* State is ON. */
        status = tx_demo_thread_slave_cdc_acm_response("RTS ON", 6);
    else
        /* State is OFF. */
        status = tx_demo_thread_slave_cdc_acm_response("RTS OFF", 7);
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_set_line_state">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_STATE</h3>
<div class="paragraph">
<p>Perform IOCTL Set Line State on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_5">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_5">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to Get the Line State parameters</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_5">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_STATE</p>
</li>
<li>
<p><strong>parameter</strong>: Pointer to a line parameter structure:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER_STRUCT
{
    UCHAR ux_slave_class_cdc_acm_parameter_rts;
    UCHAR ux_slave_class_cdc_acm_parameter_dtr;
} UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_5">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_5">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* This is to set RTS state. */

line_state.ux_slave_class_cdc_acm_parameter_rts = UX_TRUE;
status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_STATE, &amp;line_state);

/* If status is UX_SUCCESS, the operation was successful. */</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_abort_pipe">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE</h3>
<div class="paragraph">
<p>Perform IOCTL ABORT PIPE on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_6">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_6">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to abort a pipe. For example, to abort an ongoing write, UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_XMIT should be passed as the parameter.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_6">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE</p>
</li>
<li>
<p><strong>parameter</strong>: The pipe direction:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_XMIT 1

UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_RCV 2</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_6">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_ENDPOINT_HANDLE_UNKNOWN</strong> (0x53) Invalid pipe direction.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_6">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* This is to abort the Xmit pipe. */

status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE,
    UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_XMIT);

/* If status is UX_SUCCESS, the operation was successful. */</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_transmission_start">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START</h3>
<div class="paragraph">
<p>Perform IOCTL Transmission Start on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_7">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl (
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_7">Description</h3>
<div class="paragraph">
<p>This function is called when an application wants to use transmission with callback.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_7">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START</p>
</li>
<li>
<p><strong>parameter</strong>: Pointer to the Start Transmission parameter structure:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">typedef struct UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER_STRUCT
{
    UINT (*ux_device_class_cdc_acm_parameter_write_callback)(struct UX_SLAVE_CLASS_CDC_ACM_STRUCT *cdc_acm,
        UINT status, ULONG length);
    UINT (*ux_device_class_cdc_acm_parameter_read_callback)(struct UX_SLAVE_CLASS_CDC_ACM_STRUCT *cdc_acm,
        UINT status, UCHAR *data_pointer, ULONG length);
} UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_7">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_ERROR</strong> (0xFF) Transmission already started.</p>
</li>
<li>
<p><strong>UX_MEMORY_INSUFFICIENT</strong> (0x12) A memory allocation failed.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_7">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Set the callback parameter. */

callback.ux_device_class_cdc_acm_parameter_write_callback
    = tx_demo_thread_slave_write_callback;

callback.ux_device_class_cdc_acm_parameter_read_callback
    = tx_demo_thread_slave_read_callback;

/* Program the start of transmission. */
status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START, &amp;callback);

/* If status is UX_SUCCESS, the operation was successful. */</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_ioctl_ux_slave_class_cdc_acm_ioctl_transmission_stop">ux_device_class_cdc_acm_ioctl: UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_STOP</h3>
<div class="paragraph">
<p>Perform IOCTL Transmission Stop on the CDC-ACM interface</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_8">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_ioctl(
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    ULONG ioctl_function,
    VOID *parameter);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_8">Description</h3>
<div class="paragraph">
<p>This function is called when an application wants to stop using transmission with callback.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_8">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>ioctl_function</strong>: ux_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_STOP</p>
</li>
<li>
<p><strong>parameter</strong>: Not used</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_8">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_ERROR</strong> (0xFF) No ongoing transmission.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_8">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Program the stop of transmission. */

status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave,
    UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_STOP, UX_NULL);

/* If status is UX_SUCCESS, the operation was successful. */</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_read">ux_device_class_cdc_acm_read</h3>
<div class="paragraph">
<p>Read from CDC-ACM pipe</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_9">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_read(
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    UCHAR *buffer,
    ULONG requested_length,
    ULONG *actual_length);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_9">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to read from the OUT data pipe (OUT from the host, IN from the device). It is blocking.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
This functions reads raw bulk data from host, so it keeps pending until buffer is full or host terminates the transfer by a short packet (including Zero Length Packet). For more details, please refer to section <a href="#general-considerations-for-bulk-transfer"><strong>General Considerations for Bulk Transfer</strong></a>.
The function reads bytes from the host packet by packet. If the prepared buffer size is smaller than a packet and the host sends more data than expected (in other words, the prepared buffer size is not a multiple of the USB endpoint&#8217;s max packet size), then buffer overflow will occur. To avoid this issue, the recommended way to read is to allocate a buffer exactly one packet size (USB endpoint max packet size). This way if there is more data, the next read can get it and no buffer overflow will occur. If there is less data, the current read can get a short packet instead of generating an error.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_9">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>buffer</strong>: Buffer address where data will be stored.</p>
</li>
<li>
<p><strong>requested_length</strong>: The maximum length we expect.</p>
</li>
<li>
<p><strong>actual_length</strong>: The length returned into the buffer.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_9">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_CONFIGURATION_HANDLE_UNKNOWN</strong> (0x51) Device is no longer in the configured state.</p>
</li>
<li>
<p><strong>UX_TRANSFER_NO_ANSWER</strong> (0x22) No answer from device. The device was probably disconnected while the transfer was pending.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_9">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Read from the CDC class. */

status = ux_device_class_cdc_acm_read(cdc, buffer, UX_DEMO_BUFFER_SIZE, &amp;actual_length);

if(status != UX_SUCCESS) return;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_write">ux_device_class_cdc_acm_write</h3>
<div class="paragraph">
<p>Write to a CDC-ACM pipe</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_10">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_write(
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    UCHAR *buffer,
    ULONG requested_length,
    ULONG *actual_length);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_10">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to write to the IN data pipe (IN from the host, OUT from the device). It is blocking.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_10">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>buffer</strong>: Buffer address where data is stored.</p>
</li>
<li>
<p><strong>requested_length</strong>: The length of the buffer to write.</p>
</li>
<li>
<p><strong>actual_length</strong>: The length returned into the buffer after write is performed.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_10">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_CONFIGURATION_HANDLE_UNKNOWN</strong> (0x51) Device is no longer in the configured state.</p>
</li>
<li>
<p><strong>UX_TRANSFER_NO_ANSWER</strong> (0x22) No answer from device. The device was probably disconnected while the transfer was pending.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_10">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Write to the CDC class bulk in pipe. */

status = ux_device_class_cdc_acm_write(cdc, buffer, UX_DEMO_BUFFER_SIZE, &amp;actual_length);

if(status != UX_SUCCESS)
    return;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ux_device_class_cdc_acm_write_with_callback">ux_device_class_cdc_acm_write_with_callback</h3>
<div class="paragraph">
<p>Writing to a CDC-ACM pipe with callback</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_11">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_cdc_acm_write_with_callback(
    UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
    UCHAR *buffer,
    ULONG requested_length);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_11">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to write to the IN data pipe (IN from the host, OUT from the device). This function is non-blocking and the completion will be done through a callback set in <strong>UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START</strong>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_11">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>cdc_acm</strong>: Pointer to the cdc class instance.</p>
</li>
<li>
<p><strong>buffer</strong>: Buffer address where data is stored.</p>
</li>
<li>
<p><strong>requested_length</strong>: The length of the buffer to write.</p>
</li>
<li>
<p><strong>actual_length</strong>: The length returned into the buffer after write is performed</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_11">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_CONFIGURATION_HANDLE_UNKNOWN</strong> (0x51) Device is no longer in the configured state.</p>
</li>
<li>
<p><strong>UX_TRANSFER_NO_ANSWER</strong> (0x22) No answer from device. The device was probably disconnected while the transfer was pending.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_11">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Write to the CDC class bulk in pipe non blocking mode. */
status = ux_device_class_cdc_acm_write_with_callback(cdc, buffer, UX_DEMO_BUFFER_SIZE);

if(status != UX_SUCCESS)
    return;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_usb_device_cdc_ecm_class">USB Device CDC-ECM Class</h3>
<div class="paragraph">
<p>The USB device CDC-ECM class allows for a USB host system to communicate with the device as a ethernet device. This class is based on the USB standard and is a subset of the CDC standard.</p>
</div>
<div class="paragraph">
<p>A CDC-ECM compliant device framework needs to be declared by the device stack. An example is found here below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">unsigned char device_framework_full_speed[] = {

    /* Device descriptor 18 bytes
    0x02 bDeviceClass: CDC_ECM class code
    0x06 bDeviceSubclass: CDC_ECM class sub code
    0x00 bDeviceProtocol: CDC_ECM Device protocol
    idVendor &amp; idProduct - https://www.linux-usb.org/usb.ids
    0x3939 idVendor: Eclipse ThreadX test.
    */

    0x12, 0x01, 0x10, 0x01,
    0x02, 0x00, 0x00, 0x08,
    0x39, 0x39, 0x08, 0x08, 0x00, 0x01, 0x01, 0x02, 03,0x01,

    /* Configuration 1 descriptor 9 bytes. */
    0x09, 0x02, 0x58, 0x00,0x02, 0x01, 0x00,0x40, 0x00,

    /* Interface association descriptor. 8 bytes. */

    0x08, 0x0b, 0x00, 0x02, 0x02, 0x06, 0x00, 0x00,

    /* Communication Class Interface Descriptor Requirement 9 bytes */
    0x09, 0x04, 0x00, 0x00,0x01,0x02, 0x06, 0x00, 0x00,

    /* Header Functional Descriptor 5 bytes */
    0x05, 0x24, 0x00, 0x10, 0x01,

    /* ECM Functional Descriptor 13 bytes */
    0x0D, 0x24, 0x0F, 0x04,0x00, 0x00, 0x00, 0x00, 0xEA, 0x05, 0x00,
    0x00,0x00,

    /* Union Functional Descriptor 5 bytes */
    0x05, 0x24, 0x06, 0x00,0x01,

    /* Endpoint descriptor (Interrupt) */
    0x07, 0x05, 0x83, 0x03, 0x08, 0x00, 0x08,

    /* Data Class Interface Descriptor Alternate Setting 0, 0 endpoints. 9 bytes */
    0x09, 0x04, 0x01, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,

    /* Data Class Interface Descriptor Alternate Setting 1, 2 endpoints. 9 bytes */
    0x09, 0x04, 0x01, 0x01, 0x02, 0x0A, 0x00, 0x00,0x00,

    /* First alternate setting Endpoint 1 descriptor 7 bytes */
    0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,

    /* Endpoint 2 descriptor 7 bytes */
    0x07, 0x05, 0x81, 0x02, 0x40, 0x00,0x00

};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The CDC-ECM class uses a very similar device descriptor approach to the CDC-ACM and also requires an IAD descriptor. See the CDC-ACM class for definition.</p>
</div>
<div class="paragraph">
<p>In addition to the regular device framework, the CDC-ECM requires special string descriptors. An example is given below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">unsigned char string_framework[] = {
    /* Manufacturer string descriptor: Index 1 - "Eclipse ThreadX" */
    0x09, 0x04, 0x01, 0x0c,
    0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
    0x6f, 0x67, 0x69, 0x63,

    /* Product string descriptor: Index 2 - "EL CDCECM Device" */
    0x09, 0x04, 0x02, 0x10,
    0x45, 0x4c, 0x20, 0x43, 0x44, 0x43, 0x45, 0x43,
    0x4d, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x64,

    /* Serial Number string descriptor: Index 3 - "0001" */
    0x09, 0x04, 0x03, 0x04,
    0x30, 0x30, 0x30, 0x31,

    /* MAC Address string descriptor: Index 4 - "001E5841B879" */
    0x09, 0x04, 0x04, 0x0C,
    0x30, 0x30, 0x31, 0x45, 0x35, 0x38,
    0x34, 0x31, 0x42, 0x38, 0x37, 0x39

};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The MAC address string descriptor is used by the CDC-ECM class to reply to the host queries as to what MAC address the device is answering to at the TCP/IP protocol. It can be set to the device choice but must be defined here.</p>
</div>
<div class="paragraph">
<p>The initialization of the CDC-ECM class is as follows.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Set the parameters for callback when insertion/extraction of a CDC device. Set to NULL.*/
cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_activate = UX_NULL;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate = UX_NULL;

/* Define a NODE ID. */
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[0] = 0x00;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[1] = 0x1e;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[2] = 0x58;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[3] = 0x41;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[4] = 0xb8;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[5] = 0x78;

/* Define a remote NODE ID. */
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[0] = 0x00;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[1] = 0x1e;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[2] = 0x58;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[3] = 0x41;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[4] = 0xb8;
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[5] = 0x79;

/* Initialize the device cdc_ecm class. */
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name,
    ux_device_class_cdc_ecm_entry, 1,0,&amp;cdc_ecm_parameter);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The initialization of this class expects the same function callback for activation and deactivation, although here as an exercise they are set to NULL so that no callback is performed.</p>
</div>
<div class="paragraph">
<p>The next parameters are for the definition of the node IDs. 2 Nodes are necessary for the CDC-ECM, a local node and a remote node. The local node specifies the MAC address of the device, while the remote node specifies the MAC address of the host. The remote node must be the same one as the one declared in the device framework string descriptor.</p>
</div>
<div class="paragraph">
<p>The CDC-ECM class has built-in APIs for transferring data both ways but they are hidden to the application as the user application will communicate with the USB Ethernet device through NetX.</p>
</div>
<div class="paragraph">
<p>The USBX CDC-ECM class is closely tied to the NetX Duo Network stack. An application using both NetX Duo and USBX CDC-ECM class will activate the NetX network stack in its usual way but in addition needs to activate the USB network stack as follows.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Initialize the NetX Duo system. */
nx_system_initialize();

/* Perform the initialization of the network driver. This will initialize the USBX network layer.*/
ux_network_driver_init();</code></pre>
</div>
</div>
<div class="paragraph">
<p>The USB network stack needs to be activated only once and is not specific to CDCECM but is required by any USB class that requires NetX services.</p>
</div>
<div class="paragraph">
<p>The CDC-ECM class will be recognized by MAC OS and Linux hosts. But there is no driver supplied by Windows to recognize CDC-ECM natively. Some commercial products do exist for Windows platforms and they supply their own .inf file. This file will need to be modified the same way as the CDC-ACM inf template to match the PID/VID of the USB network device.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_usb_device_hid_class">USB Device HID Class</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The USB device HID class allows for a USB host system to connect to a HID device with specific HID client capabilities.</p>
</div>
<div class="paragraph">
<p>USBX HID device class is relatively simple compared to the host side. It is closely tied to the behavior of the device and its HID descriptor.</p>
</div>
<div class="paragraph">
<p>Any HID client requires first to define a HID device framework as the example below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UCHAR device_framework_full_speed[] = {
    /* Device descriptor */
    0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
    0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01,

    /* Configuration descriptor */
    0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0, 0x32,

    /* Interface descriptor */
    0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,

    /* HID descriptor */
    0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, 0x3f, 0x00,

    /* Endpoint descriptor (Interrupt) */
    0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x08

};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The HID framework contains an interface descriptor that describes the HID class and the HID device subclass. The HID interface can be a standalone class or part of a composite device. If the HID device supports multiple report, its <em>report_id</em> parameter should be set to <strong>UX_TRUE</strong>, if not it should be set to <strong>UX_FALSE</strong>.</p>
</div>
<div class="paragraph">
<p>The initialization of the HID class is as follow, using a USB keyboard as an example.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Initialize the hid class parameters for a keyboard. */
hid_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report;
hid_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH;
hid_parameter.ux_device_class_hid_parameter_callback = tx_demo_thread_hid_callback;
hid_parameter.ux_device_class_hid_parameter_get_callback = tx_demo_thread_hid_get_callback;
hid_parameter.ux_device_class_hid_parameter_report_id = 0;

/* Initialize the device hid class. The class is connected with interface 0 */

status = ux_device_stack_class_register(_ux_system_slave_class_hid_name,
    ux_device_class_hid_entry, 1,0,(VOID *)&amp;hid_parameter);
if (status!=UX_SUCCESS)
    return;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The application needs to pass to the HID class a HID report descriptor and its length. The report descriptor is a collection of items that describe the device. For more information on the HID grammar refer to the HID USB class specification.</p>
</div>
<div class="paragraph">
<p>In addition to the report descriptor, the application passes a call back when a HID event happens.</p>
</div>
<div class="paragraph">
<p>The USBX HID class supports the following standard HID commands from the host.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Command name</th>
<th class="tableblock halign-left valign-top">Value</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_DEVICE_CLASS_HID_COMMAND_GET_REPORT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0x01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Get a report from the device, callback is invoked to let application fill event</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0x02</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Get the idle frequency of the interrupt endpoint</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0x03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Get the protocol running on the device</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_DEVICE_CLASS_HID_COMMAND_SET_REPORT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0x09</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Set a report to the device, callback is invoked to notify application</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0x0a</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Set the idle frequency of the interrupt endpoint</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0x0b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Get the protocol running on the device</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The Get and Set report are the most commonly used commands by HID to transfer data back and forth between the host and the device. Most commonly the host sends data on the control endpoint but can receive data either on the interrupt endpoint or by issuing a GET_REPORT command to fetch the data on the control endpoint.</p>
</div>
<div class="paragraph">
<p>The HID class can send data back to the host on the interrupt endpoint by using the ux_device_class_hid_event_set function.</p>
</div>
<div class="sect2">
<h3 id="_ux_device_class_hid_event_set">ux_device_class_hid_event_set</h3>
<div class="paragraph">
<p>Setting an event to the HID class</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_12">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT ux_device_class_hid_event_set(
    UX_SLAVE_CLASS_HID *hid,
    UX_SLAVE_CLASS_HID_EVENT *hid_event);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_12">Description</h3>
<div class="paragraph">
<p>This function is called when an application needs to send a HID event back to the host. The function is not blocking, it merely puts the report into a circular queue and returns to the application.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_12">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>hid</strong>: Pointer to the hid class instance.</p>
</li>
<li>
<p><strong>hid_event</strong>: Pointer to structure of the hid event.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_return_value_12">Return Value</h3>
<div class="ulist">
<ul>
<li>
<p><strong>UX_SUCCESS</strong> (0x00) This operation was successful.</p>
</li>
<li>
<p><strong>UX_ERROR</strong> (0xFF) Error no space available in circular queue.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_12">Example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">/* Insert a key into the keyboard event. Length is fixed to 8. */
hid_event.ux_device_class_hid_event_length = 8;

/* First byte is a modifier byte. */
hid_event.ux_device_class_hid_event_buffer[0] = 0;

/* Second byte is reserved. */
hid_event.ux_device_class_hid_event_buffer[1] = 0;

/* The 6 next bytes are keys. We only have one key here. */
hid_event.ux_device_class_hid_event_buffer[2] = key;

/* Set the keyboard event. */
ux_device_class_hid_event_set(hid, &amp;hid_event);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The callback defined at the initialization of the HID class performs the opposite of sending an event. It gets as input the event sent by the host. The prototype of the callback is as follows.</p>
</div>
</div>
<div class="sect2">
<h3 id="_hid_callback">hid_callback</h3>
<div class="paragraph">
<p>Notify that an event is from host through control SET_REPORT request</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_13">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT hid_callback(
    UX_SLAVE_CLASS_HID *hid,
    UX_SLAVE_CLASS_HID_EVENT *hid_event);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_13">Description</h3>
<div class="paragraph">
<p>This function is called when the host sends a HID SET_REPORT to the application.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_13">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>hid</strong>: Pointer to the hid class instance.</p>
</li>
<li>
<p><strong>hid_event</strong>: Pointer to structure of the hid event.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_13">Example</h3>
<div class="paragraph">
<p>The following example shows how to interpret an event for a HID keyboard:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT tx_demo_thread_hid_callback(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event
{
    /* There was an event. Analyze it. Is it NUM LOCK ? */
    if (hid_event -&gt; ux_device_class_hid_event_buffer[0] &amp; HID_NUM_LOCK_MASK)
        /* Set the Num lock flag. */
        num_lock_flag = UX_TRUE;
    else
        /* Reset the Num lock flag. */
        num_lock_flag = UX_FALSE;

    /* There was an event. Analyze it. Is it CAPS LOCK ? */
    if (hid_event -&gt; ux_device_class_hid_event_buffer[0] &amp; HID_CAPS_LOCK_MASK)
        /* Set the Caps lock flag. */
        caps_lock_flag = UX_TRUE;
    else
        /* Reset the Caps lock flag. */
        caps_lock_flag = UX_FALSE;
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_hid_get_callback">hid_get_callback</h3>
<div class="paragraph">
<p>Notify that a host is requesting event through control GET_REPORT request</p>
</div>
</div>
<div class="sect2">
<h3 id="_prototype_14">Prototype</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT hid_get_callback(
    UX_SLAVE_CLASS_HID *hid,
    UX_SLAVE_CLASS_HID_EVENT *hid_event);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_description_14">Description</h3>
<div class="paragraph">
<p>This function is invoked when host is requesting event through control GET_REPORT
request, application must fill event structure in the callback, the data size must
not exceed the event length and the max event buffer size.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parameters_14">Parameters</h3>
<div class="ulist">
<ul>
<li>
<p><strong>hid</strong>: Pointer to the hid class instance.</p>
</li>
<li>
<p><strong>hid_event</strong>: Pointer to structure of the hid event.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_example_14">Example</h3>
<div class="paragraph">
<p>The following example shows how to prepare an event:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-c" data-lang="c">UINT tx_demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
    /* Host is asking input for GET_REPORT, prepare event data here.  */

    /* Check if report ID is used,
     * note in application the setting could be consistent so the check can be optimized.
     */
    if (hid -&gt; ux_device_class_hid_report_id)
    {
        /* First byte in buffer must be report ID, if report ID is required.
         * See HID spec. for more details.
         */
        event-&gt;ux_device_class_hid_event_report_id = demo_hid_event_report_id;
        event-&gt;ux_device_class_hid_event_report_type = demo_hid_event_report_type;
        if (demo_hid_event_length &lt; UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH - 1)
            demo_hid_event_length += 1;
        event-&gt;ux_device_class_hid_event_length = demo_hid_event_length;
        *(event-&gt;ux_device_class_hid_event_buffer) = (UCHAR)event-&gt;ux_device_class_hid_event_report_id;
        _ux_utility_memory_copy(event-&gt;ux_device_class_hid_event_buffer + 1,
                                demo_hid_event_buffer,
                                event-&gt;ux_device_class_hid_event_length - 1);
    }
    else
        /* A prepared event can be copied here. Note if copying data to event buffer,
         * keep the total size inside UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH.
         */
        _ux_utility_memory_copy(event, my_event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-02-07 08:25:21 UTC
</div>
</div>
</body>
</html>